
use serde::{Deserialize, Deserializer, Serializer};
use serde_with::{DeserializeAs, SerializeAs};
use std::fmt::Display;
use std::str::FromStr;
use crate::serde::string_other;

/// 配合`#[serde_as]`将当前类型序列化成字符串，将当前类型或字符串反序列化成当前类型
///
/// 作用同 `#[serde_as(as = "PickFirst<(_, DisplayFromStr)>")]`
pub struct DisplayParse;

impl<T> SerializeAs<T> for DisplayParse
where
    T: Display,
{
    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.collect_str(source)
    }
}

impl<'de, T> DeserializeAs<'de, T> for DisplayParse
where
    T: FromStr + Deserialize<'de>,
    T::Err: Display,
{
    fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
    where
        D: Deserializer<'de>,
    {
        string_other(deserializer)
    }
}

/// 配合`#[serde_as]`将当前类型或字符串反序列化成当前类型
///
/// 作用同 `#[serde_as(as = "PickFirst<(DisplayFromStr, _)>")]`
pub struct OnlyParse;

impl<T> SerializeAs<T> for OnlyParse
where
    T: Display + serde::Serialize,
{
    fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        source.serialize(serializer)
    }
}

impl<'de, T> DeserializeAs<'de, T> for OnlyParse
where
    T: FromStr + Deserialize<'de>,
    T::Err: Display,
{
    fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
    where
        D: Deserializer<'de>,
    {
        string_other(deserializer)
    }
}